package by.vdl.websort.controllers;

import by.vdl.websort.server.entity.CategoryDTO;
import by.vdl.websort.server.entity.ItemDTO;
import by.vdl.websort.server.entity.SortedTableDTO;
import by.vdl.websort.util.StudyManager;
import by.vdl.websort.util.view.SubmissionView;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author vasilenko
 */
@Controller
@RequestMapping(value = "/study")
@SessionAttributes({"isAuth","userDTO"})
public class StudyController extends AbstractController{

    @RequestMapping(value="/loadStudyResults", method = RequestMethod.GET)
    protected String getStudyResults(@RequestParam long studyId, @RequestParam(required=false) SubmissionView view, ModelMap map) throws Exception {

        if(view == null)
            view = SubmissionView.MODE_TABLE;

        List<SortedTableDTO> studyResults = getCommonDao().getStudyDao().getUnsortedDataSubmission(studyId);

        StudyManager studyManager = new StudyManager(getCommonDao());

        Map<Long, List<SortedTableDTO>> sortedStudyResult = studyManager.getSortedSubmissionResult(studyId);

        Map<ItemDTO, Map<CategoryDTO, Long>> submissionResultByItem = new HashMap<ItemDTO, Map<CategoryDTO, Long>>();
        Map<CategoryDTO, Map<ItemDTO, Long>> submissionResultByCategory = new HashMap<CategoryDTO, Map<ItemDTO, Long>>();

        List<ItemDTO> cashItems = new ArrayList<ItemDTO>();
        List<CategoryDTO> cashCategories = new ArrayList<CategoryDTO>();

        for(Map.Entry<Long, List<SortedTableDTO>> sortedStudyResultEntry: sortedStudyResult.entrySet()){
            List<SortedTableDTO> passedStudyByUser = sortedStudyResultEntry.getValue();

            for(SortedTableDTO sortedTable: passedStudyByUser){

                ItemDTO item = new ItemDTO(sortedTable.getItemId());
                CategoryDTO category = new CategoryDTO(sortedTable.getCategoryId());

                if(!cashItems.contains(item)){
                    item = getCommonDao().getStudyDao().getItemById(sortedTable.getItemId());
                    cashItems.add(item);
                }else{
                    item = cashItems.get(cashItems.indexOf(item));
                }

                if(!cashCategories.contains(category)){
                    category = getCommonDao().getStudyDao().getCategoryById(sortedTable.getCategoryId());
                    cashCategories.add(category);
                }else {
                    category = cashCategories.get(cashCategories.indexOf(category));
                }

                iterationByItems(submissionResultByItem, item, category);

                iterationByCategory(submissionResultByCategory, item, category);
            }
        }

        map.put("submissionResultByItem", submissionResultByItem);
        map.put("submissionResultByCategory", submissionResultByCategory);
        map.put("userCount", sortedStudyResult.size());

        switch (view){
            case MODE_M1:
                return "submissionData/dataSubmissionViewM1";
            case MODE_TABLE:
                return "submissionData/dataSubmissionViewM2";
            default:
                return "submissionData/dataSubmissionViewM2";
        }
    }

    private  void iterationByItems(Map<ItemDTO, Map<CategoryDTO, Long>> submissionResultByItem, ItemDTO item, CategoryDTO categoryDTO){
        Map<CategoryDTO, Long>  mapsCategories = null;

        try{
            mapsCategories = submissionResultByItem.get(item);
            Long count = mapsCategories.get(categoryDTO);
            mapsCategories.put(categoryDTO, ++count);

        } catch (NullPointerException npe){
            mapsCategories = (mapsCategories != null)? mapsCategories : new HashMap<CategoryDTO, Long>();
            mapsCategories.put(categoryDTO, 1L);
        }

        submissionResultByItem.put(item, mapsCategories);
    }

    private  void iterationByCategory(Map<CategoryDTO, Map<ItemDTO, Long>> submissionResultByCategory, ItemDTO item, CategoryDTO category){
        Map<ItemDTO, Long>  mapsItems = null;

        try{
            mapsItems = submissionResultByCategory.get(category);
            Long count = mapsItems.get(item);
            mapsItems.put(item, ++count);

        } catch (NullPointerException npe){
            mapsItems = (mapsItems != null)? mapsItems : new HashMap<ItemDTO, Long>();
            mapsItems.put(item, 1L);
        }
        submissionResultByCategory.put(category, mapsItems);
    }

}
